package pseudoAssemblerCompiler.twopassassembler.view.ui.autocomplete;

import org.eclipse.jface.fieldassist.ContentProposalAdapter;
import org.eclipse.jface.fieldassist.IContentProposal;
import org.eclipse.jface.fieldassist.IContentProposalProvider;
import org.eclipse.jface.fieldassist.TextContentAdapter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Text;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

/**
 * User: Selivanov
 * Date: 08.05.12
 * Time: 1:26
 */
public class AutoCompleteText<T> extends Composite {

    private ContentProposalAdapter adapter;


    private Map<String, TextDisplayFormatContentProposal> contentProposals;
    private TextDisplayFormat<T> displayFormat;
    private Text text;


    public Text getControl() {
        return text;
    }


    private IContentProposalProvider provider = new IContentProposalProvider() {
        @Override
        public IContentProposal[] getProposals(String contents, int position) {
            // Фильтрация по displayName

            List<TextDisplayFormatContentProposal> result = new ArrayList<TextDisplayFormatContentProposal>();

            // Разбиваем фильтруемый текст на слова
            StringTokenizer tokenizerFilterText = new StringTokenizer(contents);

            List<String> worlds = new ArrayList<String>();
            while (tokenizerFilterText.hasMoreElements()) {
                worlds.add(((String) tokenizerFilterText.nextElement()).toLowerCase());
            }

            for (String s : contentProposals.keySet()) {
                boolean containsAllWorlds = true;
                for (String world : worlds) {
                    if (!s.contains(world)) {
                        containsAllWorlds = false;
                        break;
                    }
                }
                if (containsAllWorlds) result.add(contentProposals.get(s));
            }

            return result.toArray(new IContentProposal[result.size()]);
        }
    };


    public AutoCompleteText(Composite parent, int style, List<T> autocompleteData, TextDisplayFormat<T> displayFormat) {
        super(parent, SWT.NONE);
        FillLayout fl = new FillLayout();
        fl.marginHeight = 0;
        fl.marginWidth = 0;
        setLayout(fl);
        this.displayFormat = displayFormat;
        setAutocompleteData(autocompleteData);
        text = new Text(this, style);
        adapter = new ContentProposalAdapter(text, new TextContentAdapter(), provider, null, null);
        adapter.setPropagateKeys(true);
        adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
    }


    public void setAutocompleteData(List<T> autocompleteData) {
        if (autocompleteData == null) autocompleteData = new ArrayList<T>();
        contentProposals = new Hashtable<String, TextDisplayFormatContentProposal>(autocompleteData.size());

        for (T element : autocompleteData) {
            contentProposals.put(displayFormat.getDisplayName(element).toLowerCase(), new TextDisplayFormatContentProposal(displayFormat, element));
        }
    }

    public AutoCompleteText(Composite parent, int style, List<T> data) {
        this(parent, style, data, new DefaultTextDisplayFormat<T>());
    }
}
